]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
iconGrid: Add openExtraSpace()/closeExtraSpace() methods
authorFlorian Müllner <fmuellner@gnome.org>
Sun, 1 Sep 2013 19:49:57 +0000 (21:49 +0200)
committerCarlos Soriano <carlos.soriano89@gmail.com>
Mon, 2 Sep 2013 18:36:39 +0000 (20:36 +0200)
Add methods to open/close extra space for n rows. The app picker
will use those to make AppFolder popups appear inline with the
main grid rather than on top of it.

https://bugzilla.gnome.org/show_bug.cgi?id=706081

js/ui/iconGrid.js

index 8e792274950a0b2878613bf1e163d1c181e11629..178a8419b9427995963f45cb9de1acae5eaea232 100644 (file)
@@ -1,14 +1,18 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
+const Gtk = imports.gi.Gtk;
 const Shell = imports.gi.Shell;
+const Signals = imports.signals;
 const St = imports.gi.St;
 
 const Lang = imports.lang;
 const Params = imports.misc.params;
+const Tweener = imports.ui.tweener;
 
 const ICON_SIZE = 48;
 
+const EXTRA_SPACE_ANIMATION_TIME = 0.25;
 
 const BaseIcon = new Lang.Class({
     Name: 'BaseIcon',
@@ -573,5 +577,102 @@ const PaginatedIconGrid = new Lang.Class({
             return 0;
         }
         return Math.floor(index / this._childrenPerPage);
+    },
+
+    /**
+    * openExtraSpace:
+    * @sourceItem: the item for which to create extra space
+    * @side: where @sourceItem should be located relative to the created space
+    * @nRows: the amount of space to create
+    *
+    * Pan view to create extra space for @nRows above or below @sourceItem.
+    */
+    openExtraSpace: function(sourceItem, side, nRows) {
+        let children = this._getVisibleChildren();
+        let index = children.indexOf(sourceItem.actor);
+        if (index == -1) {
+            throw new Error('Item not found.');
+            return;
+        }
+        let pageIndex = Math.floor(index / this._childrenPerPage);
+        let pageOffset = pageIndex * this._childrenPerPage;
+
+        let childrenPerRow = this._childrenPerPage / this._rowsPerPage;
+        let sourceRow = Math.floor((index - pageOffset) / childrenPerRow);
+
+        let nRowsAbove = (side == St.Side.TOP) ? sourceRow + 1
+                                               : sourceRow;
+        let nRowsBelow = this._rowsPerPage - nRowsAbove;
+
+        let nRowsUp, nRowsDown;
+        if (side == St.Side.TOP) {
+            nRowsDown = Math.min(nRowsBelow, nRows);
+            nRowsUp = nRows - nRowsDown;
+        } else {
+            nRowsUp = Math.min(nRowsAbove, nRows);
+            nRowsDown = nRows - nRowsUp;
+        }
+
+        let childrenDown = children.splice(pageOffset +
+                                           nRowsAbove * childrenPerRow,
+                                           nRowsBelow * childrenPerRow);
+        let childrenUp = children.splice(pageOffset,
+                                         nRowsAbove * childrenPerRow);
+
+        // Special case: On the last row with no rows below the icon,
+        // there's no need to move any rows either up or down
+        if (childrenDown.length == 0 && nRowsUp == 0) {
+            this._translatedChildren = [];
+            this.emit('space-opened');
+        } else {
+            this._translateChildren(childrenUp, Gtk.DirectionType.UP, nRowsUp);
+            this._translateChildren(childrenDown, Gtk.DirectionType.DOWN, nRowsDown);
+            this._translatedChildren = childrenUp.concat(childrenDown);
+        }
+    },
+
+    _translateChildren: function(children, direction, nRows) {
+        let translationY = nRows * (this._vItemSize + this._getSpacing());
+        if (translationY == 0)
+            return;
+
+        if (direction == Gtk.DirectionType.UP)
+            translationY *= -1;
+
+        for (let i = 0; i < children.length; i++) {
+            children[i].translation_y = 0;
+            let params = { translation_y: translationY,
+                           time: EXTRA_SPACE_ANIMATION_TIME,
+                           transition: 'easeInOutQuad'
+                         };
+            if (i == (children.length - 1))
+                params.onComplete = Lang.bind(this,
+                    function() {
+                        this.emit('space-opened');
+                    });
+            Tweener.addTween(children[i], params);
+        }
+    },
+
+    closeExtraSpace: function() {
+        if (!this._translatedChildren || !this._translatedChildren.length) {
+            this.emit('space-closed');
+            return;
+        }
+
+        for (let i = 0; i < this._translatedChildren.length; i++) {
+            if (!this._translatedChildren[i].translation_y)
+                continue;
+            Tweener.addTween(this._translatedChildren[i],
+                             { translation_y: 0,
+                               time: EXTRA_SPACE_ANIMATION_TIME,
+                               transition: 'easeInOutQuad',
+                               onComplete: Lang.bind(this,
+                                   function() {
+                                       this.emit('space-closed');
+                                   })
+                             });
+        }
     }
 });
+Signals.addSignalMethods(PaginatedIconGrid.prototype);